﻿using AbpIntegrationDemo.Api.Applications.Orders.GraphTypes;
using AbpIntegrationDemo.Api.Applications.Orders.Mutations;
using AbpIntegrationDemo.Api.Applications.Orders.Queries;
using AbpIntegrationDemo.Api.EntityFrameworkCores;
using AbpIntegrationDemo.Api.Infrastructures.GraphQLs;
using Microsoft.OpenApi.Models;
using Volo.Abp;
using Volo.Abp.AspNetCore.Mvc;
using Volo.Abp.AspNetCore.Serilog;
using Volo.Abp.Autofac;
using Volo.Abp.EntityFrameworkCore;
using Volo.Abp.EntityFrameworkCore.MySQL;
using Volo.Abp.Modularity;
using Volo.Abp.Swashbuckle;

namespace AbpIntegrationDemo.Api;

[DependsOn(
    typeof(AbpAspNetCoreMvcModule),
    typeof(AbpAutofacModule),
    typeof(AbpSwashbuckleModule),
    typeof(AbpAspNetCoreSerilogModule),
    typeof(AbpEntityFrameworkCoreMySQLModule)
    )]
public class AbpIntegrationDemoModule : AbpModule
{
    public override void ConfigureServices(ServiceConfigurationContext context)
    {
        var services = context.Services;

        services.AddAbpSwaggerGen(options =>
        {
            options.SwaggerDoc("v1", new OpenApiInfo { Title = "AbpIntegrationDemo.Api", Version = "v1" });
            options.DocInclusionPredicate((docName, description) => true);
            options.CustomSchemaIds(type => type.FullName);
        });

        services.AddAbpDbContext<AppDbContext>(options =>
        {
            options.AddDefaultRepositories();
        });

        Configure<AbpDbContextOptions>(options =>
        {
            options.UseMySQL();
        });

        services.AddGraphQLServer()
            .AddQueryType()
            .AddMutationType()
            .AddType<OrderGraphType>()
            .AddType<OrderLogGraphType>()
            .AddTypeExtension<OrderQueryResolver>()
            .AddTypeExtension<OrderExtendQueryResolver>()
            .AddTypeExtension<OrderMutationResolver>()
            .UseExceptions()
            .UseTimeout()
            .UseDocumentCache()
            .UseDocumentParser()
            .UseDocumentValidation()
            .UseOperationCache()
            .UseOperationComplexityAnalyzer()
            .UseOperationResolver()
            .UseOperationVariableCoercion()
            .UseRequest<UnitOfWorkMiddleware>()
            .UseOperationExecution();
    }

    public override void OnApplicationInitialization(ApplicationInitializationContext context)
    {
        var app = context.GetApplicationBuilder();
        var env = context.GetEnvironment();

        app.UseStaticFiles();
        app.UseSwagger();
        app.UseAbpSwaggerUI(options =>
        {
            options.SwaggerEndpoint("/swagger/v1/swagger.json", "AbpIntegrationDemo API");
        });

        app.UseRouting();
        app.UseAbpSerilogEnrichers();
        app.UseConfiguredEndpoints();
        app.UseConfiguredEndpoints(endpoints =>
        {
            endpoints.MapGraphQL();
        });
    }
}
